package org.feuyeux.opentracing;

import com.google.common.collect.ImmutableMap;
import io.dropwizard.Application;
import io.dropwizard.Configuration;
import io.dropwizard.setup.Environment;
import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.Tracer;
import lombok.extern.slf4j.Slf4j;
import org.feuyeux.opentracing.lib.HttpClient;
import org.feuyeux.opentracing.lib.Tracing;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.util.concurrent.TimeUnit;

@Slf4j
public class HelloA extends Application<Configuration> {
    private final Tracer tracer;
    private final HttpClient client;

    private HelloA(Tracer tracer) {
        this.tracer = tracer;
        client = new HttpClient(tracer);
    }

    @Path("/x")
    @Produces(MediaType.TEXT_PLAIN)
    public class FormatterResource {

        @GET
        public String x(
                @QueryParam("r") String r,
                @QueryParam("s") String s,
                @QueryParam("t") String t,
                @Context HttpHeaders httpHeaders) {
            Span span = Tracing.startServerSpan(tracer, httpHeaders, "a-x");
            try (Scope scope = tracer.scopeManager().activate(span)) {
                String xResult = badBehavior(s);
                String yResult = y(xResult);
                String yResult2 = client.getHttp(8082, "y", ImmutableMap.of(
                        "t", t,
                        "s", yResult));
                return yResult2;
            } finally {
                span.finish();
            }
        }

        private String badBehavior(String v) {
            StringBuilder result = new StringBuilder();
            String[] ss = v.split(",");
            for (String s : ss) {
                result.append(client.getHttp(8082, "x", ImmutableMap.of("s", s))).append(",");
            }
            return result.toString();
        }

        private String y(String r) {
            Span span = tracer.buildSpan("a-y").start();
            try (Scope scope = tracer.scopeManager().activate(span)) {
                log.info("r:{}", r);
                TimeUnit.MILLISECONDS.sleep(100);
                span.log(ImmutableMap.of("event", "y"));
            } catch (InterruptedException e) {
                log.error("", e);
            } finally {
                span.finish();
            }
            return "y(" + r + ")";
        }
    }

    @Override
    public void run(Configuration configuration, Environment environment) throws Exception {
        environment.jersey().register(new FormatterResource());
    }

    public static void main(String[] args) throws Exception {
        System.setProperty("dw.server.applicationConnectors[0].port", "8081");
        System.setProperty("dw.server.adminConnectors[0].port", "9081");
        new HelloA(Tracing.init("A")).run(args);
    }
}
